package com.baseproject.datasource.remote;


import com.baseproject.appconfig.ConstUrlBaseProject;
import com.baseproject.BaseApplication;
import com.baseproject.BuildConfig;
import com.baseproject.util.ByteUtil;
import com.baseproject.util.LogUtils;
import com.baseproject.util.NetworkUtils;

import java.io.IOException;
import java.util.concurrent.TimeUnit;

import okhttp3.Cache;
import okhttp3.CacheControl;
import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;

public class RetrofitUtil {

    //创建Cache
//    static Cache cache = BaseApplication.getApplication() != null ?
//            new Cache(new File(BaseApplication.getApplication().getCacheDir(), "HttpCache"), 10 * 1024 * 1024) : null;

    static Cache cache = null;

    static int sMaxTryCount = 5;

    private static HttpLoggingInterceptor logInterceptor = new HttpLoggingInterceptor()
            .setLevel(BuildConfig.LOG_HTTP_ENABLE ? HttpLoggingInterceptor.Level.HEADERS : HttpLoggingInterceptor.Level.NONE);


    private static Interceptor networkInterceptor = new Interceptor() {
        @Override
        public Response intercept(Chain chain) throws IOException {
            Request original = chain.request();
            Request request = addHeader(original);
            if (cache != null) {
                return addCache(chain, request);
            } else {
                return chain.proceed(request);
            }
        }
    };

    private static OkHttpClient client = cache != null ? new OkHttpClient.Builder()
            .cache(cache)
            .addInterceptor(networkInterceptor)
            .addInterceptor(logInterceptor)
            .addNetworkInterceptor(networkInterceptor)
            .connectTimeout(10, TimeUnit.SECONDS)
            .build() :
             new OkHttpClient.Builder()
            .addInterceptor(networkInterceptor)
            .addInterceptor(logInterceptor)
            .addNetworkInterceptor(networkInterceptor)
            .connectTimeout(10, TimeUnit.SECONDS)
            .build();


    /**
     * Cache-control 是由服务器返回的 Response 中添加的头信息，它的目的是告诉客户端是要从本地读取缓存还是直接从服务器摘取消息。它有不同的值，每一个值有不同的作用。
     * 没网的情况下Request 直接从缓存里面读取，响应体增加header的Cache-Control，缓存30天，
     * 有网的情况下，Request 就会去请求服务器，然后响应体就会去都Retrofit框架里面的@Header配置，
     * 如果没有配置，就不缓存，如果配置了就可以进行缓存。到这里，当我们去Get请求的时候，就会生成缓存
     */
    private static Response addCache(Interceptor.Chain chain, Request request) throws IOException {
        if (!NetworkUtils.isNetworkAvailable()) {
            //无网络下强制使用缓存，无论缓存是否过期,此时该请求实际上不会被发送出去。
            request = request.newBuilder().cacheControl(CacheControl.FORCE_CACHE)
                    .build();
        }
        Response response = chain.proceed(request);
        if (NetworkUtils.isNetworkAvailable()) { //有网络情况下，根据请求接口的设置，配置缓存。这样在下次请求时，根据缓存决定是否真正发出请求。
            //当然如果你想在有网络的情况下都直接走网络，那么只需要将其超时时间这是为0即可:String cacheControl="Cache-Control:public,max-age=0"
            String cacheControl = request.cacheControl().toString();
            return response.newBuilder().header("Cache-Control", cacheControl)
                    .removeHeader("Pragma")
                    .build();
        } else { //无网络
            return response.newBuilder().header("Cache-Control", "public,only-if-cached,max-stale=30*24*60*60")
                    .removeHeader("Pragma")
                    .build();
        }
    }

    private static Response proceedRequest(Interceptor.Chain chain, Request request, int currentRetryCount) {
        Response response = null;
        try {
            response = chain.proceed(request);
        } catch (IOException e) {
            LogUtils.logCatchedException(e);
            if (currentRetryCount < sMaxTryCount) {
                return proceedRequest(chain, request, ++currentRetryCount);
            } else {
                LogUtils.e("stop retrying! e = " + e);
            }
        }
        return response;
    }

    private static Request addHeader(Request original) {
        BaseApplication baseApplication = BaseApplication.getApplication();
        String channel;
        String version;

        if (baseApplication == null) {
            channel = "";
            version = "";
        } else {
            channel = ByteUtil.getUmengChannel(baseApplication.getApplicationContext());
            version = ByteUtil.getClientVersion(baseApplication.getApplicationContext());
        }
        //添加三个header参数，剩下的token动态添加
        return original.newBuilder()
                .header("x-version", version == null ? "" : version)
                .header("x-channel", channel == null ? "" : channel)
                .header("client", "android")
                .method(original.method(), original.body())
                .build();
    }

    private static Retrofit retrofit = new Retrofit.Builder()
            .baseUrl(ConstUrlBaseProject.TEST_URL)
            .addConverterFactory(GsonConverterFactory.create())
            .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
            .client(client)
            .build();

    public static <T> T createService(Class<T> tClass) {
        return retrofit.create(tClass);
    }


}
